using Assets.Scripts.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;
using HashTable = ExitGames.Client.Photon.Hashtable;

public class RoundManager : MonoBehaviourPunCallbacks
{
    #region 单例模式
    public static RoundManager Instance;
    void Awake()
    {
        Instance = this;
    }
    #endregion


    // 当前回合的牌库
    public CardDefine[] cards;
    public CharacterCard[] charCards;   // 角色卡库

    // 当前卡牌索引，当前抽到了第多少张牌
    public int currCardIndex = 0;

    #region 网络相关
    HashTable CardTable = new HashTable();

    private void Start()
    {
        CardTable.Add("cards", cards);
        CardTable.Add("charCards", charCards);
        CardTable.Add("index", currCardIndex);
    }

    public override void OnPlayerPropertiesUpdate(Photon.Realtime.Player targetPlayer, HashTable changedProps)
    {
        if (!PhotonNetwork.IsMasterClient)
        {
            cards = (CardDefine[])changedProps["cards"];
            charCards = (CharacterCard[])changedProps["charCards"];
            
        }

        currCardIndex = (int)changedProps["index"];

    }
    #endregion


    /// <summary>
    /// 进入游戏
    /// </summary>
    public void EnterGame()
    {
        // 清除可能存在的脏数据
        StopAllCoroutines();
        Player.Instance.StopAllCoroutines();
        Player.Instance.RemoveAllCard();
        Enemy.Instance.RemoveAllCard();


        if (PhotonNetwork.IsMasterClient)
        {
            // 洗牌，TODO:需要网络化，由房主来洗牌
            cards = CardManager.Instance.Shuffle();
            CardTable["cards"] = cards;
            currCardIndex = 0;

            charCards = CardManager.Instance.InitCharCard();
            CardTable["charCards"] = charCards;
            PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
        }

        // 初始化玩家血量
        Player.Instance.CurrHP = 4;
        // 初始化敌人血量
        Enemy.Instance.CurrHP = 4;

        // 发四张初始卡-玩家
        PlayerGetCardByNum(4);
        // 发四张初始卡-敌人
        EnemyGetCardByNum(4);

        // 开启检测游戏是否结束
        StartCoroutine(CheckGameOver());
        // 开启检测角色阵亡的协程
        StartCoroutine(CheckCharDeath());
        // 进入游戏主刷新
        StartCoroutine(UpdateRound());
    }


    #region 回合循环
    /// <summary>
    /// 主刷新
    /// </summary>
    private IEnumerator UpdateRound()
    {
        // 只要一方没死，就一直循环
        while (true)
        {
            // 玩家回合
            if (UIMain_Panel.Instance.IsMyTurn == true)
            {
                selectedCardCount = 0;    //若已选卡牌数=2，选择卡牌按钮无法使用，只能跳过，若已选卡牌数<2，则不能跳过，只能选牌

                getCardsPanel.SetActive(true);  //依次打开所有抽卡面板
                beltPanel.SetActive(true);

                // 初始化传送带
                UIBelt_Panel.Instance.currBeltCardDic = new Dictionary<int, CardDefine>()
                {
                    [0] = Instance.cards[Instance.currCardIndex],
                    [1] = Instance.cards[Instance.currCardIndex + 1],
                    [2] = Instance.cards[Instance.currCardIndex + 2],
                    [3] = Instance.cards[Instance.currCardIndex + 3]
                };

                for (int i = 0; i < 4; i++) //刷新一遍传送带的UI显示
                {
                    UpdateBeltCard(i, UIBelt_Panel.Instance.currBeltCardDic[i]);
                }

                yield return StartCoroutine(PlayerGetCard()); //等玩家抽完卡

                yield return StartCoroutine(Player.Instance.EnterRound());  //正式进入玩家回合
            }
            // 现在是对方的回合
            EnemyGetCardByNum(2);    // 其实并不用为敌人脚本写摸牌方法，主要是要更新敌人的手牌数，进而刷新手牌剩余数的UI
            yield return StartCoroutine(Enemy.Instance.EnterRound());
        }
    }
    #endregion


    #region 抽卡阶段
    public GameObject getCardsPanel;    //抽卡面板
    public GameObject beltPanel;         //传送带抽卡面板
    public GameObject normalGetCardPanel;    //正常抽牌面板

    private bool isClickOkButton;   // 玩家是否按下了确认抽牌按钮

    int selectedCardCount;

    #region 传送带卡牌更新
    /// <summary>
    /// 刷新传送带上的卡
    /// </summary>
    public void UpdateBeltCard(int cardID, CardDefine card)
    {
        for (int i = 0; i < 4; i++)
        {
            if (UIBelt_Panel.Instance.uIBelt_Items[i].cardID == cardID)
            {
                UIBelt_Panel.Instance.uIBelt_Items[i].Init(cardID, card);
            }
        }
    }
    #endregion

    /// <summary>
    /// 玩家点击了确认摸牌按钮
    /// </summary>
    public void OkButtonClick()
    {
        Player.Instance.GetCard(GetCard());
        selectedCardCount++;
        isClickOkButton = true;

        for (int i = 0; i < 4; i++) //刷新一遍传送带的UI显示
        {
            UpdateBeltCard(i, UIBelt_Panel.Instance.currBeltCardDic[i]);
        }
    }
    /// <summary>
    /// 玩家跳过按钮，用来切换传送带或者普通抽牌界面
    /// </summary>
    public void SkipButtonClick()
    {
        if (beltPanel.activeInHierarchy)
        {
            beltPanel.SetActive(false);
            normalGetCardPanel.SetActive(true);
        }
        else
        {
            normalGetCardPanel.SetActive(false);
            beltPanel.SetActive(true);
        }
    }

    private IEnumerator PlayerGetCard()
    {
        while (selectedCardCount < 2) // 牌没抽够两张就会一直等你抽完再进入主回合
        {
            while (!isClickOkButton)
            {
                yield return null;  // 卡住进程，等待玩家按下按钮
            }
            // 按完按钮后取反，继续卡住你的进程
            if (isClickOkButton)
                isClickOkButton = false;
            // TODO:还需要卡住对方的进程
        }
        normalGetCardPanel.SetActive(false);    // 依次关闭所有抽卡面板
        beltPanel.SetActive(false);
        getCardsPanel.SetActive(false);


    }
    /// <summary>
    /// 通过准确的数字来获取卡牌，一般用于角色初始化
    /// </summary>
    private IEnumerator PlayerGetCardByNum(int count)
    {
        for (int i = 0; i < count; i++)
        {
            Player.Instance.GetCard(GetCard());
        }
        yield return null;
    }


    private void EnemyGetCardByNum(int count)
    {
        for (int i = 0; i < count; i++)
        {
            Enemy.Instance.GetCard(GetCard());
        }
    }

    /// <summary>
    /// 抽一张卡
    /// </summary>
    private CardDefine GetCard()
    {
        // 如果卡抽完了 随机一副新卡
        if (currCardIndex + 5 >= cards.Length)  // 若房主此次抽牌是在抽第最大牌数-5张，就洗一次牌
        {
            if (PhotonNetwork.IsMasterClient)
            {
                // 重新获取一副卡
                cards = CardManager.Instance.Shuffle();
                currCardIndex = 0;

                CardTable["index"] = currCardIndex;
                PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
            }
        }

        CardDefine card = null;
        for (int i = 0; i < 4; i++)
        {
            int itemIndex = -1;     // 用来记录是玩家是在选中哪张卡的情况下进行点击获取卡牌的
            if (UIBelt_Panel.Instance.uIBelt_Items[i].IsSelect)
            {
                UIBelt_Panel.Instance.currBeltCardDic.TryGetValue(i, out card);
                itemIndex = i;
            }

            switch (itemIndex)
            {
                case -1:
                    break;
                case 0:
                    UIBelt_Panel.Instance.currBeltCardDic[0] = Instance.cards[Instance.currCardIndex + 1];
                    UIBelt_Panel.Instance.currBeltCardDic[1] = Instance.cards[Instance.currCardIndex + 3];
                    currCardIndex += 1;
                    CardTable["index"] = currCardIndex;
                    PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
                    UIBelt_Panel.Instance.currBeltCardDic[3] = Instance.cards[Instance.currCardIndex + 3];
                    break;
                case 1:
                    UIBelt_Panel.Instance.currBeltCardDic[1] = Instance.cards[Instance.currCardIndex + 3];
                    currCardIndex += 1;
                    CardTable["index"] = currCardIndex;
                    PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
                    UIBelt_Panel.Instance.currBeltCardDic[3] = Instance.cards[Instance.currCardIndex + 3];
                    break;
                case 2:
                    UIBelt_Panel.Instance.currBeltCardDic[2] = Instance.cards[Instance.currCardIndex + 1];
                    UIBelt_Panel.Instance.currBeltCardDic[1] = Instance.cards[Instance.currCardIndex + 3];
                    currCardIndex += 1;
                    CardTable["index"] = currCardIndex;
                    PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
                    UIBelt_Panel.Instance.currBeltCardDic[3] = Instance.cards[Instance.currCardIndex + 3];
                    break;
                case 3:
                    currCardIndex += 1;
                    CardTable["index"] = currCardIndex;
                    PhotonNetwork.LocalPlayer.SetCustomProperties(CardTable);
                    UIBelt_Panel.Instance.currBeltCardDic[3] = Instance.cards[Instance.currCardIndex + 3];
                    break;
            }
        }

        // 更新卡库的数字
        UIMain_Panel.Instance.UpdateStandByCard_All(cards.Length - currCardIndex);
        return card;
    }
    #endregion


    #region 流程控制
    /// <summary>
    /// 有角色阵亡，停止回合循环
    /// </summary>
    IEnumerator CheckCharDeath()
    {
        while (true)
        {
            yield return null;
            bool isDeath = Player.Instance.CurrHP <= 0 || Enemy.Instance.CurrHP <= 0;
            // 如果当前有玩家血量归零，则进入阵亡角色选角色阶段
            if (isDeath)
            {
                GameManager.Instance.GameState = GameState.WaittingExchangeChar;

                // TODO:停止玩家的出牌阶段协程，开启选择角色面板和御守面板
                StopCoroutine(UpdateRound());
                StopCoroutine(CheckCharDeath());
            }
        }
    }

    /// <summary>
    /// 某一方玩家角色阵亡数 = 3，游戏结束
    /// </summary>
    IEnumerator CheckGameOver()
    {
        while (true)
        {
            yield return null;
            if (Player.Instance.playerDeathCount == 3 || Enemy.Instance.enemyDeathCount == 3)
            {
                GameManager.Instance.GameState = GameState.Over;
                StopCoroutine(CheckGameOver());
            }
        }
    }
    #endregion


}
